package com.jt.www.common.controller;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.jt.www.common.service.ContractService;
import com.jt.www.common.service.ZqService;
import com.jt.www.common.service.zqsign.param.agreement.Param;
import com.jt.www.exception.ServiceException;
import com.jt.www.model.reps.GenericDataResponse;
import com.jt.www.model.reps.GenericListResponse;
import com.jt.www.model.zq.ZqContract;
import com.jt.www.model.zq.ZqParam;
import com.jt.www.model.zq.ZqVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.List;


/**
 * @描述： 众签接口
 * @作者： lux
 * @创建日期： 2018-9-6 16:43
 * @版权： 江泰保险经纪股份有限公司
 */
@Api(value = "众签接口", tags = {"Zq-API"}, description = "众签接口")
@RestController
@RequestMapping("/api/")
public class ZqController {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ZqService zqService;
    @Autowired
    private ContractService contractService;


    /**
     * 创建企业数字证书
     *
     * @return
     */
    @ApiOperation(value = "创建企业数字证书")
    @PostMapping(value = "regEnterprise", produces = {MediaType.APPLICATION_JSON_VALUE})
    public String regEnterprise(@ApiParam(name = "files", value = "公章", required = true) @RequestParam("files") MultipartFile file,
                                @ApiParam(name = "branchName", value = "机构名称") @RequestParam("branchName") String branchName,

                                @ApiParam(name = "branchCode", value = "机构编码") @RequestParam("branchCode") String branchCode,
                                @ApiParam(name = "address", value = "详细地址") @RequestParam("address") String address,
                                @ApiParam(name = "certificate", value = "三证合一") @RequestParam("certificate") String certificate,
                                @ApiParam(name = "mobile", value = "手机号") @RequestParam("mobile") String mobile,
                                @ApiParam(name = "contact", value = "联系人") @RequestParam("contact") String contact) {
        log.info("创建企业数字证书");
        String returnmsg = zqService.regEnterprise(certificate, address, contact, mobile, branchCode, branchName);
        JSONObject json = JSONObject.parseObject(returnmsg);
        if (json.getString("code").equals("0")) {
            returnmsg = zqService.signatureChange(branchCode, file);
            return returnmsg;
        }
        return returnmsg;
    }

    /**
     * 更新企业数字证书
     *
     * @return
     */
    @ApiOperation(value = "更新企业数字证书")
    @PostMapping(value = "updateEnterprise", produces = {MediaType.APPLICATION_JSON_VALUE})
    public String updateEnterprise(@ApiParam(name = "files", value = "公章", required = true) @RequestParam("files") MultipartFile file,
                                   @ApiParam(name = "branchName", value = "机构名称", required = true) @RequestParam("branchName") String branchName,
                                   @ApiParam(name = "branchCode", value = "机构编码", required = true) @RequestParam("branchCode") String branchCode,
                                   @ApiParam(name = "address", value = "详细地址", required = true) @RequestParam("address") String address,
                                   @ApiParam(name = "certificate", value = "三证合一", required = true) @RequestParam("certificate") String certificate,
                                   @ApiParam(name = "mobile", value = "手机号", required = true) @RequestParam("mobile") String mobile,
                                   @ApiParam(name = "contact", value = "联系人", required = true) @RequestParam("contact") String contact) {
        log.info("更新企业数字证书");
        String returnmsg = zqService.updateEnterprise(certificate, address, contact, mobile, branchCode, branchName);
        JSONObject json = JSONObject.parseObject(returnmsg);
        if (json.getString("code").equals("0")) {
            returnmsg = zqService.signatureChange(branchCode, file);
            return returnmsg;
        }
        return returnmsg;
    }


    /**
     * 上传公章
     *
     * @return
     */
    @ApiOperation(value = "上传公章")
    @PostMapping(value = "signatureChange", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE})
    public String signatureChange(@RequestParam("files") MultipartFile file, @RequestParam("userCode") String userCode) {
        log.info("上传公章");
        return zqService.signatureChange(userCode, file);
    }

    /**
     * @param agreementParam
     * @return
     * @throws ServiceException
     */
    @ApiOperation(value = "新建委托协议", notes = "新建委托协议", httpMethod = "POST")
    @PostMapping(value = "/agreement", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> agreement(@RequestBody @ApiParam(name = "新建委托协议参数", value = "传入json格式", required = true)
                                       @Valid Param agreementParam) throws ServiceException {
        try {
            return contractService.saveAgreement(agreementParam);
        } catch (Exception e) {
            log.error("创建协议接口/agreement", e.getMessage());
            return GenericDataResponse.ng(e.getMessage());
        }
    }


    /**
     * 生成合同模板
     *
     * @return
     */
    @ApiOperation(value = "生成合同模板")
    @PostMapping(value = "createTemplate", produces = {MediaType.APPLICATION_JSON_VALUE})
    public String createTemplate(@RequestParam("files") MultipartFile file) {
        log.info("创建合同");
        return zqService.createTemplate(file);
    }


    /**
     * @param no 协议号
     * @return String  返回类型
     * @Title: 获取合同pdf地址
     */
    @ApiOperation(value = "获取合同pdf地址")
    @GetMapping(value = "contract_site", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> contractSite(@RequestParam(value = "no") String no) {
        String pdfUrl = null;
        try {
            pdfUrl = zqService.getPdfUrl(no);
        } catch (Exception e) {
            log.error("异步回调接口/notifyUrl，异常：{}", e.getMessage());
            return GenericDataResponse.ng(e.getMessage());
        }
        return GenericDataResponse.okWithData(pdfUrl);
    }

    /**
     * @param userCode 用户编码
     * @return String  返回类型
     * @Title: 通过用户获取合同pdf地址
     */
    @ApiOperation(value = "获取合同pdf地址")
    @GetMapping(value = "contract_file", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> contractFile(@RequestParam(value = "userCode") String userCode) {
        String pdfUrl = contractService.contractFile(userCode);
        return GenericDataResponse.okWithData(pdfUrl);
    }

    /**
     * @Title: 通过用户编码获取协议列表
     */
    @ApiOperation(value = "通过用户编码获取合同列表，app端")
    @GetMapping(value = "contract_list", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> contractFileList(@RequestParam(value = "userCode") String userCode) {
        List<ZqContract> list = contractService.contractFileList(userCode);
        return GenericListResponse.listNoCount(list);
    }

    /**
     * @Title: 多条件获取协议列表
     */
    @ApiOperation(value = "多条件获取合同列表，pc管理端")
    @PostMapping(value = "contract_list", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> contractList(@RequestBody ZqParam zqParam) {
        PageInfo<ZqVO> pageInfo = null;
        try {
            pageInfo = contractService.contractList(zqParam);
        } catch (Exception e) {
            return GenericDataResponse.ng(e.getMessage());
        }
        return GenericDataResponse.okWithData(pageInfo);
    }

    /**
     * @Title: 多条件获取协议列表excel post请求暂时不用
     */
    @ApiIgnore
    @ApiOperation(value = "多条件获取协议列表excel，pc管理端")
    @PostMapping(value = "contract_excel", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public void contractExcel(@RequestBody ZqParam zqParam, HttpServletResponse response) {
        try {
            contractService.contractListByExcel(zqParam, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @Title: 多条件获取协议列表excel
     */
    @ApiOperation(value = "多条件获取协议列表excel，pc管理端")
    @GetMapping(value = "contract_excel", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public void contractExcelV2(ZqParam zqParam, HttpServletResponse response) {
        try {
            contractService.contractListByExcel(zqParam, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @Title: 通过合同编号获取合同pdf文件流
     */
    @ApiOperation(value = "通过协议编号获取合同")
    @GetMapping(value = "contract/{no}", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public void contract(@PathVariable(value = "no") String no, HttpServletResponse response) throws Exception {
        byte[] buffer = new byte[1024];
        int len = -1;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String pdfUrl = null;
        try {
            pdfUrl = zqService.getPdfUrl(no);
        } catch (Exception e) {
            log.error("协议文件下载：{}", e.getMessage());
        }
        HttpGet httpGet = new HttpGet(pdfUrl);
        try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
             InputStream input = httpResponse.getEntity().getContent();
             OutputStream output = response.getOutputStream()) {
            //设置响应头
            response.addHeader("Content-Type", "application/pdf");
            response.addHeader("content-disposition", "attachment;filename=\"" + URLEncoder.encode(no + ".pdf", "UTF-8") + "\"");
            //从输入流中读取文件
            while ((len = input.read(buffer)) != -1) {
                //将buffer数组写入到文件中，从0开始写入的长度为实际读取到的长度len,如果使用write(buffer);会出现中文乱码及图像变模糊的问题
                output.write(buffer, 0, len);
            }
        } catch (FileNotFoundException e) {
            log.error(e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * @param no
     * @return ResponseEntity  返回类型
     * @Title: 获取合同图片地址
     */
    @ApiOperation(value = "获取合同图片地址")
    @GetMapping(value = "get_img", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity getImg(@RequestParam(value = "no") String no) {
        List imgList = zqService.getImg(no);
        return GenericListResponse.listNoCount(imgList);
    }

    /**
     * @param request
     * @return
     * @throws ParseException
     * @throws IOException
     */
    @ApiOperation(value = "异步回调接口")
    @PostMapping(value = "/notifyUrl", produces = {MediaType.APPLICATION_JSON_VALUE})
    public String notifyUrl(HttpServletRequest request) throws ParseException, IOException {
        log.info("=======================异步回调接口");
        String code = request.getParameter("code");
        String no = request.getParameter("no");
        log.info("=======================code" + code);
        log.info("=======================no" + no);
        if (!StringUtils.isEmpty(code) && code.equals("0")) {
            return contractService.updateAgreement(no);
        }
        throw new ServiceException("调用异步接口失败");
    }

    @ApiOperation(value = "是否已经签署合同")
    @GetMapping(value = "/logged/{idCode}/{name}", produces = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity islogged(@PathVariable("idCode") String idCode, @PathVariable("name") String name) {
        return GenericDataResponse.okWithData(contractService.judgeIsSign(idCode, name));
    }

    @ApiOperation(value = "修改个人签证")
    @GetMapping(value = "/sign/{name}/{idCode}/{phoneNo}", produces = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity sign(@PathVariable("userCode") String userCode, @PathVariable("idCode") String idCode, @PathVariable("phoneNo") String phoneNo) {
        return GenericDataResponse.okWithData(zqService.updatePersonReg(userCode, idCode, phoneNo));
    }

    @ApiIgnore
    @GetMapping(value = "/test", produces = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity test(String param) {
        log.info(param);
        return GenericDataResponse.ok();
    }
}
